package com.softwinner.awbt.fragment;

import android.app.ProgressDialog;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.softwinner.awbt.R;
import com.softwinner.awbt.activity.MainActivity;
import com.softwinner.awbt.adapter.DeviceAdapter;
import com.softwinner.awbt.common.BTApplication;
import com.softwinner.awbt.common.BTPreference;
import com.softwinner.awbt.controller.BTController;
import com.softwinner.awbt.listener.SettingListener;
import com.softwinner.awbt.model.BTDeviceInfo;
import com.softwinner.awbt.utils.LOG;

import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.List;


/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * to handle interaction events.
 * Use the {@link SettingsFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class SettingsFragment extends BaseFragment implements View.OnClickListener,
        SettingListener {

    private EditText mNameEditText;
    private Button mRenameButton;
    private Button mScanButton;
    private ListView mDiscoveryListView;
    private TextView mConnectedTextView;
    private Switch mAutoConnectSwitch;
    private Switch mAutoAnswerSwitch;
    private LinearLayout mConnectLayout;
    private LinearLayout mDiscoveryLayout;
    private MainActivity mActivity;
    private ProgressBar mScanProgressBar;
    private TextView mAddressTextView;
    private Button mDisconnectButton;
    private ProgressDialog mProgressDialog;
    private DeviceAdapter mAdapter;
    private List<BTDeviceInfo> mDeviceInfos = new ArrayList<>();
    private static SettingListener sSettingListener;
    private String mWaitConnectAddress;

    private final int MSG_SCAN_TIMEOUT = 0xff01;
    private final int MSG_CONNECT_TIMEOUT = 0xff02;
    private final int MSG_CONNECT_DELAY = 0xff03;
    private final int MAX_TIME = 60 * 1000;

    private String mCurrentAddress;
    private String mCurrentName;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SCAN_TIMEOUT:
                    mScanButton.setEnabled(true);
                    mScanProgressBar.setVisibility(View.GONE);
                    showMessage(mScanButton, R.string.scan_timeout);
                    break;
                case MSG_CONNECT_TIMEOUT:
                    mWaitConnectAddress = null;
                    dismissProgressDialog();
                    showMessage(mScanButton, R.string.connect_timeout);
                    break;
                case MSG_CONNECT_DELAY:
                    String address = (String) msg.obj;
                    mActivity.doConnect(address);
                    break;
            }
        }
    };

    public SettingsFragment() {
        // Required empty public constructor
        sSettingListener = this;
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @return A new instance of fragment SettingsFragment.
     */
    public static SettingsFragment newInstance() {
        return new SettingsFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
            savedInstanceState) {
        LOG.d("SettingFragment ---onCreateView");
        View view = inflater.inflate(R.layout.fragment_settings, container, false);
        initView(view);
        return view;
    }

    private void initView(View view) {
        mNameEditText = (EditText) view.findViewById(R.id.name_et);
        mAutoAnswerSwitch = (Switch) view.findViewById(R.id.auto_answer_s);
        mAutoConnectSwitch = (Switch) view.findViewById(R.id.auto_connect_s);
        mConnectedTextView = (TextView) view.findViewById(R.id.connected_tv);
        mDiscoveryListView = (ListView) view.findViewById(R.id.discovery_lv);
        mRenameButton = (Button) view.findViewById(R.id.rename_b);
        mScanButton = (Button) view.findViewById(R.id.scan_b);
        mConnectLayout = (LinearLayout) view.findViewById(R.id.connected_ll);
        mDiscoveryLayout = (LinearLayout) view.findViewById(R.id.discovery_ll);
        mScanProgressBar = (ProgressBar) view.findViewById(R.id.scan_pb);
        mAddressTextView = (TextView) view.findViewById(R.id.connected_address_tv);
        mDisconnectButton = (Button) view.findViewById(R.id.disconnected_b);


        mAdapter = new DeviceAdapter(getContext(), mDeviceInfos);
        mDiscoveryListView.setAdapter(mAdapter);
        mRenameButton.setOnClickListener(this);
        mScanButton.setOnClickListener(this);
        mDisconnectButton.setOnClickListener(this);
        mNameEditText.setText(BTPreference.getInstance(getContext()).getDeviceName());
        mAutoAnswerSwitch.setChecked(BTPreference.getInstance(getContext()).isAutoAnswer());
        mAutoConnectSwitch.setChecked(BTPreference.getInstance(getContext()).isAutoConnect());
        mRenameButton.setVisibility(View.INVISIBLE);
        mRenameButton.requestFocus();
        mAutoConnectSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if (b == BTPreference.getInstance(getContext()).isAutoConnect()) {
                    return;
                }
                if (BTApplication.getInstance().getStatus() >= BTApplication.STATUS_INIT) {
                    mActivity.setAutoConnect(b);
                } else {
                    Toast.makeText(getContext(), R.string.app_init_alert, Toast.LENGTH_SHORT)
                            .show();
                }
            }
        });

        mAutoAnswerSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if (b == BTPreference.getInstance(getContext()).isAutoAnswer()) {
                    return;
                }
                if (BTApplication.getInstance().getStatus() >= BTApplication.STATUS_INIT) {
                    mActivity.setAutoAnswer(b);
                } else {
                    Toast.makeText(getContext(), R.string.app_init_alert, Toast.LENGTH_SHORT)
                            .show();
                }

            }
        });
        mNameEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                String name = mNameEditText.getText().toString();
                if (BTPreference.getInstance(getContext()).getDeviceName().equals(name)) {
                    mRenameButton.setVisibility(View.INVISIBLE);
                } else {
                    mRenameButton.setVisibility(View.VISIBLE);
                }

            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });

        mDiscoveryListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                checkAndConnect(mDeviceInfos.get(i));
            }
        });

        if (TextUtils.isEmpty(mCurrentAddress)) {
            mConnectLayout.setVisibility(View.GONE);
        } else {
            mConnectedTextView.setText(mCurrentName);
            mAddressTextView.setText(mCurrentAddress);
            mConnectLayout.setVisibility(View.VISIBLE);
        }
    }

    private void checkAndConnect(BTDeviceInfo deviceInfo) {
        showProgressDialog();
        mHandler.sendEmptyMessageDelayed(MSG_CONNECT_TIMEOUT, MAX_TIME);
        String address = deviceInfo.getAddress();
        mConnectedTextView.setText(getString(R.string.name) + ":" + deviceInfo.getName());
        mAddressTextView.setText(getString(R.string.address) + ":" + address);

        if (BTApplication.getInstance().getStatus() >= BTApplication.STATUS_CONNECTED) {
            if (!address.equals(BTApplication.getInstance().getCurrentAddress())) {
                mActivity.disConnected();
                mWaitConnectAddress = address;
            }else {
                dismissProgressDialog();
            }
        } else {
            mActivity.doConnect(address);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        LOG.d("SettingsFragment--onAttach-");
        if (context instanceof MainActivity) {
            mActivity = (MainActivity) context;
        }
    }

    @Override
    public void onDestroyView() {
        LOG.d("SettingsFragment--onDestroyView-");
        super.onDestroyView();
    }

    @Override
    public void onDetach() {
        LOG.d("SettingsFragment--onDetach-");
        sSettingListener = null;
        mActivity = null;
        super.onDetach();
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.scan_b:
                if (BTApplication.getInstance().getStatus() >= BTApplication.STATUS_DISCONNECTED) {
                    mActivity.doScan();
                    mScanButton.setEnabled(false);
                    mScanProgressBar.setVisibility(View.VISIBLE);
                    mHandler.sendEmptyMessageDelayed(MSG_SCAN_TIMEOUT, MAX_TIME);
                }
                break;
            case R.id.rename_b:
                if (BTApplication.getInstance().getStatus() >= BTApplication.STATUS_INIT) {
                    mActivity.doRename(mNameEditText.getText().toString());
                }
                break;
            case R.id.disconnected_b:
                mActivity.disConnected();
                break;
        }

    }

    @Override
    public void onCurrentName(String name) {
        mCurrentName = name;
        mHandler.removeMessages(MSG_CONNECT_TIMEOUT);
        if (mConnectedTextView != null) {
            String info = getString(R.string.name) + ":" + name;
            mConnectedTextView.setText(info);
            mConnectLayout.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void onCurrentAddress(String address) {
        dismissProgressDialog();
        mCurrentAddress = address;
        if (mAddressTextView != null) {
            String info = getString(R.string.address) + ":" + address;
            mAddressTextView.setText(info);
            mConnectLayout.setVisibility(View.VISIBLE);
            mScanButton.setEnabled(true);
        }
    }

    @Override
    public void onCurrentDeviceName(String name) {
        if (mNameEditText != null && !TextUtils.isEmpty(name) && !name.equals(BTPreference
                .getInstance(getContext()).getDeviceName())) {
            mNameEditText.setText(name);

        }
    }

    @Override
    public void onConnected() {
        mWaitConnectAddress = null;
    }

    @Override
    public void onDisconnected() {
        mCurrentName = null;
        mCurrentAddress = null;
        if (mConnectLayout == null) {
            return;
        }
        mConnectLayout.setVisibility(View.GONE);

        if (!TextUtils.isEmpty(mWaitConnectAddress)) {
            mActivity.doConnect(mWaitConnectAddress);
        }
    }

    @Override
    public void onStopConnect() {

    }

    @Override
    public void onAutoConnect(boolean autoConnect) {
        BTPreference.getInstance(getContext()).setAutoConnect(autoConnect);
        if (mAutoConnectSwitch == null) {
            return;
        }
        if (autoConnect != mAutoConnectSwitch.isChecked()) {
            mAutoConnectSwitch.setChecked(autoConnect);
        }
    }

    @Override
    public void onAutoAnswer(boolean autoAnswer) {
        BTPreference.getInstance(getContext()).setAutoAnswer(autoAnswer);
        if (mAutoAnswerSwitch == null) {
            return;
        }
        if (autoAnswer != mAutoAnswerSwitch.isChecked()) {
            mAutoAnswerSwitch.setChecked(autoAnswer);
        }
    }

    @Override
    public void onStopScan() {
        if (mScanButton == null) {
            return;
        }
        mScanButton.setEnabled(true);
        mScanProgressBar.setVisibility(View.GONE);
        mHandler.removeMessages(MSG_SCAN_TIMEOUT);
    }

    @Override
    public void onScanDevice(String name, String address) {
        BTDeviceInfo deviceInfo = new BTDeviceInfo(name, address);
        if (!mDeviceInfos.contains(deviceInfo)) {
            mDeviceInfos.add(deviceInfo);
        }

        if (mDiscoveryListView != null) {
            mAdapter.notifyDataSetChanged();
        }
    }


    public static SettingListener getListener() {
        return sSettingListener;
    }

    private void showProgressDialog() {
        if (isDetach()) {
            return;
        }
        mProgressDialog = new ProgressDialog(getContext());
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        mProgressDialog.setCanceledOnTouchOutside(false);
        mProgressDialog.setMessage(getString(R.string.connecting));
        mProgressDialog.show();
    }

    private void dismissProgressDialog() {
        if (mProgressDialog != null) {
            mProgressDialog.dismiss();
            mProgressDialog = null;
        }
    }
}